package com.steve.summary.tcc;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: STEVE
 * @Description: 库存服务TCC实现（扣减库存场景）
 * @since: 2025-05-23
 */
public class InventoryService implements TccParticipant {

    private static final String SERVICE_NAME = "inventory"; // 服务标识

    // 模拟数据库表结构
    private static class InventoryItem {
        String skuId;       // 商品SKU
        int stock;          // 当前库存
        int frozenStock;    // 冻结库存（Try阶段预留）
    }

    private final Map<String, InventoryItem> inventoryTable = new ConcurrentHashMap<>();
    private final TransactionLog transactionLog; // 共享事务日志

    public InventoryService(TransactionLog transactionLog) {
        this.transactionLog = transactionLog;
        // 初始化测试数据
        InventoryItem item = new InventoryItem();
        item.skuId = "SKU_001";
        item.stock = 100; // 初始库存100
        inventoryTable.put("SKU_001", item);
    }

    @Override
    public boolean tryExecute(String txId, int reduceAmount) {
        // 防悬挂检查（如果已存在Cancel记录，拒绝Try）
        if (transactionLog.isCancelRecordExists(txId, SERVICE_NAME)) {
            throw new IllegalStateException("[Inventory] 存在Cancel记录，拒绝Try操作");
        }
        InventoryItem item = inventoryTable.get("SKU_001");
        synchronized (item) {
            if(item.stock >= reduceAmount) {
                item.stock -= reduceAmount;
                item.frozenStock += reduceAmount;
                transactionLog.logTry(txId, SERVICE_NAME, "LOCK_" + reduceAmount);
                System.out.println("[Inventory] Try成功，冻结库存: " + reduceAmount);
                return true;
            }
        }
        System.out.println("[Inventory] Try失败，库存不足");
        return false;
    }

    @Override
    public boolean confirm(String txId) {
        // 幂等性检查
        if (transactionLog.isConfirmRecordExists(txId, SERVICE_NAME)) {
            System.out.println("[Inventory] Confirm已执行，跳过");
            return true;
        }
        InventoryItem item = inventoryTable.get("SKU_001");
        synchronized (item) {
            item.frozenStock = 0; // 清除冻结库存（实际扣减已完成）
            transactionLog.logConfirm(txId, SERVICE_NAME);
            System.out.println("[Inventory] Confirm完成，实际扣减库存");
        }
        return true;
    }

    @Override
    public boolean cancel(String txId) {
        // 空回滚处理（未执行Try直接Cancel）
        if (!transactionLog.isTryRecordExists(txId, SERVICE_NAME)) {
            transactionLog.logCancel(txId, SERVICE_NAME, true);
            System.out.println("[Inventory] 空回滚，无Try记录");
            return true;
        }
        // 幂等性检查
        if (transactionLog.isCancelRecordExists(txId, SERVICE_NAME)) {
            System.out.println("[Inventory] Cancel已执行，跳过");
            return true;
        }
        InventoryItem item = inventoryTable.get("SKU_001");
        synchronized (item) {
            String tryData = transactionLog.getTryData(txId, SERVICE_NAME);
            int amount = Integer.parseInt(tryData.split("_")[1]);
            item.stock += amount; // 恢复库存
            item.frozenStock -= amount;
            transactionLog.logCancel(txId, SERVICE_NAME, false);
            System.out.println("[Inventory] Cancel完成，释放库存：" + amount);
        }
        return true;
    }

    // 查询当前库存（测试用）
    public int getCurrentStock() {
        return inventoryTable.get("SKU_001").stock;
    }

    // 查询冻结库存（测试用）
    public int getFrozenStock() {
        return inventoryTable.get("SKU_001").frozenStock;
    }

}
